package com.qut.atcoder.service.impl;

import com.qut.atcoder.mappers.QuestionMapper;
import com.qut.atcoder.mappers.UserQuestionMapper;
import com.qut.atcoder.pojo.Question;
import com.qut.atcoder.pojo.UserQuestion;
import com.qut.atcoder.service.UserQuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Paths;

@Service
public class UserQuestionServiceImpl implements UserQuestionService {
    private  final String path = "C:\\Users\\Public\\Documents\\atcode\\judger\\";

    @Autowired(required = false)
    private QuestionMapper questionMapper;

    @Autowired(required = false)
    UserQuestionMapper userQuestionMapper;

    @Override
    public int answer(UserQuestion userQuestion) {
        String[] strings = new String[]{"gcc",path + "main.cpp", "-o",path + "main.exe"};
        Question question = new Question();
        question.setIs_exist(1);
        question.setId(userQuestion.getQuestion_id());
        question = questionMapper.selectQuestionById(question).get(0);
        try {
            Files.write(Paths.get("C:\\Users\\Public\\Documents\\atcode\\judger\\main.cpp")
                    ,userQuestion.getCode().getBytes());
            Process process = Runtime.getRuntime().exec(strings);
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            return 2;
        }

        try {//实际上只能测试一组数据
            copy("C:\\Users\\Public\\Documents\\atcode\\question\\" + question.getId() + "\\0.in",
                    path + "in.txt");
            copy("C:\\Users\\Public\\Documents\\atcode\\question\\" + question.getId() + "\\0.out",
                    path + "out.txt");
            Process process = Runtime.getRuntime().exec(path + "main.exe");
            OutputStream outputStream = process.getOutputStream();
            InputStream inputStream = process.getInputStream();
            PrintStream printStream = new PrintStream(outputStream);
            InputStream in = new FileInputStream(path + "in.txt");
            InputStream out = new FileInputStream(path + "out.txt");
            byte[] in_txt = in.readAllBytes();
            byte[] out_txt = out.readAllBytes();
            printStream.print(byteToChar(in_txt));
            Thread.sleep(question.getTime_limit());
            //睡眠结束后直接读取
            //但是不知道下面这个会不会阻塞等待
            byte[] ans = inputStream.readAllBytes();
            if (out_txt.length != ans.length) {
                userQuestion.setState(1);
                userQuestionMapper.insertUserQuestion(userQuestion);
                return 1;
            }
            for (int i = 0; i < out_txt.length; i++) {
                if (out_txt[i] != ans[i]) {
                    userQuestion.setState(1);
                    return  1;
                }
            }
            userQuestion.setState(0);
            return 0;
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            return 3;
        }
    }

    // byte转为char
    public static char[] byteToChar(byte[] bytes) {
        Charset charset = StandardCharsets.ISO_8859_1;
        ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
        byteBuffer.put(bytes);
        byteBuffer.flip();
        CharBuffer charBuffer = charset.decode(byteBuffer);
        return charBuffer.array();
    }
    //将一个路径上的文件复制到另一个路径上
    public static void copy(String oldpath, String newpath) throws IOException {
        File oldpaths = new File(oldpath);
        File newpaths = new File(newpath);
        if (!newpaths.exists()) {
            Files.copy(oldpaths.toPath(), newpaths.toPath());
        } else {
//            newpaths.delete();
            try {
                Files.copy(oldpaths.toPath(), newpaths.toPath());
            } catch (FileAlreadyExistsException e) {
                newpaths.delete();
                Files.copy(oldpaths.toPath(), newpaths.toPath());
            }

        }
    }

}
